package rigby.projects.wikipediawebcrawler;

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;

public class WebCrawlerDataMethods {

	/**getValidLink method
	 * 		Parses the given Document
	 *		Selects a valid link (under <p>) & finds its parent
	 * 		If link exists & parent is found, calls parenthesisCheck
	 * 			If an error is caught, calls getAltLink 
	 * 
	 * @param urlDoc
	 * 		Document of current URL containing links
	 * @param visitedSites
	 * 		ArrayList<String> of previously visited links
	 * @param jumpNum
	 * 		Int number of jumps since crawl began
	 * @return finalLink
	 * 		String URL of valid link
	 */
	public String getValidLink(Document urlDoc){
		Element linkElement = urlDoc.select("div#mw-content-text p a[href ^=/wiki/]:not(table a):not(a[href ^=/wiki/Wikipedia:]):not(a[href ^=/wiki/File:]").first();		
		Element linkParent = null;
		String finalLink = null;
		
		try {
		linkParent = linkElement.parent();
		finalLink = parenthesisCheck(linkParent);
		} catch (Exception e){
			finalLink = getAltLink(urlDoc);
		}
		
		return finalLink;
	}

	/**getAltLink method
	 * 		Alternate method to getValidLink
	 * 		Only called if getValidLink cannot find a link
	 * 			(Usually due to lack of <p></p>)
	 * 		
	 * 		Parses the given DOcument
	 * 		Selects a validLink (not necessarily under <p>) & finds its parent
	 * 		Calls parenthesisCheck
	 * 
	 * @param urlDoc
	 * 		Document of current URL containing links
	 * @return finalLink
	 * 		String URL of valid link
	 */
	public String getAltLink(Document urlDoc) {
		Element linkElement = urlDoc.select("div#mw-content-text a[href]:not(span a):not(table a):not(.image):not(sup a)").first();
		Element linkParent = linkElement.parent();
		
		String finalLink = parenthesisCheck(linkParent);
		
		return finalLink;
	}
	
	/**parenthesisCheck method
	 * 		Cycles through each node of a given parent
	 * 		Checks each TextNode for "(" or ")"
	 * 		Using boolean isInParenthesis, gives each non-TextNode a state
	 * 		If an element has tagName a && is in a false state: breaks
	 * 
	 * @param linkParent
	 * 		Element parent of the desired link
	 * @return finalLink
	 * 		String URL of fully-checked link 
	 */
	public String parenthesisCheck(Element linkParent){
		boolean isInParenthesis = false;
		String finalLink = null;
		
		for(Node node : linkParent.childNodes()){
			if(node instanceof org.jsoup.nodes.TextNode && ((org.jsoup.nodes.TextNode) node).text().contains("(")){
				isInParenthesis = true;
			}
			if(node instanceof org.jsoup.nodes.TextNode && ((org.jsoup.nodes.TextNode) node).text().contains(")")){
				isInParenthesis = false;
			}
			if(node instanceof org.jsoup.nodes.Element && ((Element) node).tagName()=="a" && isInParenthesis==false){
				finalLink = node.attr("abs:href");
				break;
			}
			else{
				
			}
		}
		
		return finalLink;
		
		}
			
	/**getRandomLink method
	 * 		Connects to & parses a random wikipedia page
	 * 		Then converts the URL to a String 
	 * 
	 * @return randomLink
	 * 		String URL of randomly generated link
	 */
	public String getRandomLink() {
		String randomLink = null;
		while (true) {
			try {
				Document randomLinkDoc = Jsoup.connect("http://en.wikipedia.org/wiki/Special:Random").get();
			randomLink = randomLinkDoc.baseUri();
			break;
		} catch (IOException e) {
			System.out.println("Error: getRandomLink returned invalid link.");
			WebCrawler wc = new WebCrawler();
			wc.crawlUrl(getRandomLink());
		}
	}
		return randomLink;	
	}
}
